package pers.cz.easyexcel.dao;

import org.apache.commons.collections4.ListUtils;
import org.apache.poi.EmptyFileException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import pers.cz.common.connect.ConnectionFactory;
import pers.cz.common.connect.IConnection;
import pers.cz.common.connect.StoreType;
import pers.cz.common.pub.AbstractEntity;
import pers.cz.common.pub.CommonDao;
import pers.cz.easyexcel.analysis.XlsxAnalysiser;
import pers.cz.easyexcel.localfile.LocalFileConnectionFactory;
import pers.cz.easyexcel.write.XlsxFileWriter;
import utils.TimeLag;

import java.io.*;
import java.util.List;

/**
 * @program: Jef-orm
 * @description: 抽象文件操作类
 * @author: Cheng Zhi
 * @create: 2023-09-04 21:02
 **/
public abstract class AbstractFileDao implements CommonDao {

    IConnection connection;
    String fileName;
    File file;

    public AbstractFileDao(File file) {
        // 初始化连接池
        ConnectionFactory connectionFactory = new LocalFileConnectionFactory(file);
        this.connection = connectionFactory.getConnection(StoreType.LOCALFILE);
        this.fileName = file.getName();
        this.file = file;
    }

    protected List<AbstractEntity> analysisFile(AbstractEntity entity) throws IOException, IllegalAccessException, InstantiationException {

        if (fileName.endsWith(".xlsx")) {
           return new XlsxAnalysiser(entity, getWorkBook()).analysis();
        } else if (fileName.endsWith(".xls")) {
        }
        connection.close();
        return null;
    }

    /**
     * 单行写入
     * @param entity
     * @param isUpdate
     * @throws IOException
     */
    protected void writeFile(AbstractEntity entity, Boolean isUpdate) throws IOException {

        if (fileName.endsWith(".xlsx")) {
            // 由于excel的特殊性,空文件是不允许写入的，空文件写入会抛出org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)异常
            XSSFWorkbook workbook = (XSSFWorkbook) getWorkBook();
            new XlsxFileWriter(entity, workbook).write(isUpdate);
            FileOutputStream outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            outputStream.flush();
            close(workbook, outputStream);
        }
    }

    /**
     * 删除
     * @param entity
     * @throws IOException
     */
    protected void remove(AbstractEntity entity) throws IOException {
        if (fileName.endsWith(".xlsx")) {
            // 由于excel的特殊性,空文件是不允许写入的，空文件写入会抛出org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)异常
            XSSFWorkbook workbook = (XSSFWorkbook) getWorkBook();
            new XlsxFileWriter(entity, workbook).remove();
            FileOutputStream outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            outputStream.flush();
            close(workbook, outputStream);
        }
    }

    protected void writeFile(List<AbstractEntity> entities) throws IOException {
        if (fileName.endsWith(".xlsx")) {
            // 由于excel的特殊性,空文件是不允许写入的，空文件写入会抛出org.apache.poi.EmptyFileException: The supplied file was empty (zero bytes long)异常
            XSSFWorkbook workbook = (XSSFWorkbook) getWorkBook();

            for (AbstractEntity entity : entities) {
                new XlsxFileWriter(entity, workbook).write(false);
            }

            FileOutputStream outputStream = new FileOutputStream(file);
            workbook.write(outputStream);
            close(workbook, outputStream);
        }
    }

    private Workbook getWorkBook() throws IOException {

        Workbook workbook = null;
        if (fileName.endsWith(".xlsx")) {
            try {
                workbook = new XSSFWorkbook((InputStream) connection.getConnectin());
            } catch (EmptyFileException e) {
                // 文件不存在，则新建
                workbook = new XSSFWorkbook();
            }
        } else if (fileName.endsWith(".xls")) {
            workbook = new HSSFWorkbook();
        }

        return workbook;
    }

    private void close(Workbook workbook, Closeable closeable) throws IOException {
        workbook.close();
        closeable.close();
        connection.close();
    }

}
